(function ($) {
	/*
	window.SITE_URL = window.SITE_URL || '';
	if (document.location.href.indexOf('http://') != 0)	{
		var path = '../control/treetable/';
	} else {
		rootURL = $("#ctx").val();
		var path = rootPath + '/asset/js/control/treetable/';
	}
	*/
    $.fn.treeTable = function (opts) {
        var opts = $.extend({
            theme: 'default',
            expandLevel: 6,
            column: 0,
            onSelect: function($treeTable, id){},
            beforeExpand: function($treeTable, id){}
        }, opts);

        var $treeTable = this;
		
		if (!$treeTable.hasClass('tree_table')) {
			$treeTable.addClass('tree_table');
		} else {
			return false;
		}        

        //添加需要的样式
		/*
        if ($('head').find('#tree_table_' + opts.theme).length == 0) {
            $('head').append('<link id="tree_table_' + opts.theme + '" href="' + path + opts.theme + '/jquery.treeTable.css" rel="stylesheet" type="text/css" />');
        }
		*/
		
		opts.theme = 'vsStyle';
		
        var css = {
            'N' : opts.theme + '_node',
            'AN' : opts.theme + '_active_node',
            'O' : opts.theme + '_open',
            'LO' : opts.theme + '_last_open',
            'S' : opts.theme + '_shut',
            'LS' : opts.theme + '_last_shut',
            'HO' : opts.theme + '_hover_open',
            'HS' : opts.theme + '_hover_shut',
            'HLO' : opts.theme + '_hover_last_open',
            'HLS' : opts.theme + '_hover_last_shut',
            'L' : opts.theme + '_leaf',
            'LL' : opts.theme + '_last_leaf',
            'B' : opts.theme + '_blank',
            'V' : opts.theme + '_vertline'
        };

        var pMap = {}, cMap = {};
        var $trs = $treeTable.css({visibility: 'hidden'}).find('tr');
		var trsLen = $trs.length; //SSUI
		var trsObj = {}; // SSUI        

		// SSUI
		$.each($trs, function(idx, ele){

			var id = (typeof $(ele).attr('id') == 'undefined') ? '' : $(ele).attr('id');
			trsObj[id] = ele;
			
			if (idx == trsLen - 1) {
				initRelation($trs, true);
			}
		});
		
        $treeTable.click(function (event) {
            var $target = $(event.target);

            if ($target.attr('controller')) {
                $target = $target.parents('tr[haschild]').find('[arrow]');
                //判断是否是叶子节点
				if ($target.attr('class').indexOf(css['AN']) == -1 && $target.attr('class').indexOf(css['N']) == -1) { return; }
                var id = $target.parents('tr[haschild]')[0].id;
                if (opts.onSelect && opts.onSelect($treeTable, id) === false) { return; }
            }

            if ($target.attr('arrow')) {
                var className = $target.attr('class');
                if (className == css['AN'] + ' ' + css['HLO'] || className == css['AN'] + ' ' + css['HO']) {
                    var id = $target.parents('tr[haschild]')[0].id;
                    $target.attr('class', css['AN'] + " " + (className.indexOf(css['HO']) != -1 ?  css['HS'] : css['HLS']));

                    //关闭所有孩子的tr
                    shut(id);
					return;
                } else if (className == css['AN'] + ' ' + css['HLS'] || className == css['AN'] + ' ' + css['HS']) {
                    var id = $target.parents('tr')[0].id;
                    $target.attr('class', css['AN'] + " " + (className.indexOf(css['HS']) != -1 ? css['HO'] : css['HLO']));
                    
                    opts.beforeExpand($treeTable, id);
                    //展开所有直属节点，根据图标展开子孙节点
                    open(id);
					return;
                }
            }
        });
		
		$treeTable.mouseover(hoverActiveNode).mouseout(hoverActiveNode);

        function hoverActiveNode(event) {
            var $target = $(event.target);

            if ($target.attr('controller')) {
                $target = $target.parents('tr[haschild]').find('[arrow]');
            }

            if ($target.attr('arrow')) { 
                var className = $target.attr('class');
                if (className && !className.indexOf(css['AN'])) {
                    var len = opts.theme.length + 1;
                    className = className.split(' ')[1].substr(len);
                    if (className.indexOf('hover_') === 0) {
                        className = opts.theme + '_' + className.substr(6);
                    } else {
                        className = opts.theme + '_hover_' + className;
                    }
                    
                    $target.attr('class', css['AN'] + ' ' + className);
                    return;
                }
            } 
        }
        
        /** 初始化节点关系　*/
        function initRelation($trs, hideLevel) {
            
			// SSUI
			var ttlDone = 0;
			var isReordered = false;
			var reorderTr = function(parentId){			

				setTimeout(function(){
					
					if (parentId in pMap) {
						
						$.each([].concat(pMap[parentId]).reverse(), function(idx, ele){
							
							if (parentId == 0) {
								$treeTable.prepend(trsObj[ele]);
							} else {
								$('#' + parentId).after(trsObj[ele]);
							}							
							
							trsLen--;
							ttlDone++;													
							reorderTr(ele);
						});
					} else {
						$treeTable.css({visibility:'visible'});
					}
					
					if (trsLen == 0 && isReordered == false) {
						fatherFindKid();
						isReordered = true;						
					}
					
				//}, 10 * ttlDone);
				}, 0);
			};
			
			//构造父子关系
            $trs.each(function (idx, ele) {
                var pId = $(this).attr('pId') || 0;
                pMap[pId] || (pMap[pId] = []);
                pMap[pId].push(this.id);
                cMap[this.id] = pId;
                
                //给这个tr增加类为了提高选择器的效率
                $(this).addClass(pId);
				
				// SSUI				
				if (idx == trsLen - 1) {
					reorderTr(0);
				}
            }).find('[controller]').css('cursor', 'pointer');			
			
			
            //标识父节点是否有孩子、是否最后一个节点
            function fatherFindKid(){
				// SSUI: get the reordered trs!!!
				var $tr = $treeTable.css({visibility:'visible'}).find('tr');
				
				$tr.each(function (i) {
					if (!this.id) { return; }
					var $tr = $(this);
					
					pMap[this.id] && $tr.attr('hasChild', true);
					var pArr = pMap[cMap[this.id]];
					if (pArr[0] == this.id) {
						$tr.attr('isFirstOne', true);
					} else {
						var prevId = 0;
						for (var i = 0; i < pArr.length; i++) {
							if (pArr[i] == this.id) { break; }
							prevId = pArr[i];
						}
						$tr.attr('prevId', prevId);
					}

					pArr[pArr.length - 1] == this.id && $tr.attr('isLastOne', true);

					var depth = getDepth(this.id);
					$tr.attr('depth', depth);

					//格式化节点
					formatNode(this);

					//判断是否要隐藏限制的层次
					if (hideLevel) {
						
						// SSUI
						if (depth > opts.expandLevel) {
							$tr.hide();
						}

						//判断是否小于深度，如果小于深度则要换成展开的图标
						if ($tr.attr('hasChild') && $tr.attr('depth') < opts.expandLevel) {
							var className = $tr.attr('isLastOne') ? css['LO'] : css['O'];
							$tr.find('.' + css['AN']).attr('class', css['AN'] + ' ' + className);
						}
					}               
				});
			}
            
            //递归获取深度
            function getDepth(id) {
                if (cMap[id] == 0) { return 1; } 
                var $parentDepth = getDepth(cMap[id]);
                return $parentDepth + 1; 
            }
        }

        //递归关闭所有的孩子
        function shut(id) {
            if (!pMap[id]) { return false; }
            for (var i = 0; i < pMap[id].length; i++) {
                shut(pMap[id][i]);
            }
            $('tr.' + id, $treeTable).hide();
        }

        //根据历史记录来展开节点
        function open(id) {
            $('tr.' + id, $treeTable).show();
            if (!pMap[id]) { return false; }
            for (var i = 0; i < pMap[id].length; i++) {
                var cId = pMap[id][i];
                if (pMap[cId]) {
                    var className = $('#' + cId, $treeTable).find('.' + css['AN']).attr('class');
                    //如果子节点是展开图表的，则需要展开此节点
                    (className == css['AN'] + ' ' + css['O'] || className == css['AN'] + ' ' + css['LO']) && open(cId);
                }
            }
        }

        function formatNode(tr) {
            var $cur = $(tr);
            var id = tr.id;

            //-------------下面一大段都是获取$preSpan---------
            if (cMap[id] == 0) {
                //如果是顶级节点，则没有prev_span
                var $preSpan = $('<span class="prev_span"></span>');
            } else {
                //先判断是否有上一个兄弟节点
                if (!$cur.attr('isFirstOne')) {
                    var $preSpan = $('#' + $cur.attr('prevId'), $treeTable).children("td").eq(opts.column).find('.prev_span').clone();
                } else {
                    var $parent = $('#' + cMap[id], $treeTable);
                    //没有上一个兄弟节点，则使用父节点的prev_span
                    var $preSpan = $parent.children("td").eq(opts.column).find('.prev_span').clone();

                    //如果父亲后面没有兄弟，则直接加空白，若有则加竖线
                    if ($parent.attr('isLastOne')) {
                        $preSpan.append('<span class="' + css['N'] + ' ' + css['B'] + '"></span>');
                    } else {
                        $preSpan.append('<span class="' + css['N'] + ' ' + css['V'] + '"></span>');
                    }
                }
            }
            //------------------------------------------------

            if ($cur.attr('hasChild')) {
                //如果有下一个节点，并且下一个节点的父亲与当前节点的父亲相同，则说明该节点不是最后一个节点
                var className = $cur.attr('isLastOne') ? css['LS'] : css['S'];
                className = css['AN'] + ' ' + className;
            } else {
                var className = css['N'] + ' ' + ($cur.attr('isLastOne') ? css['LL'] : css['L']);
            }
            
            var $td = $cur.children("td").eq(opts.column);
            $td.prepend('<span arrow="true" class="' + className + '"></span>').prepend($preSpan);
        };
        
        $treeTable.addChilds = function(trsHtml) {
            var $trs = $(trsHtml);
            if (!$trs.length) { return false; }
            
            var pId = $($trs[0]).attr('pId');
            if (!pId) { return false; }
            
            //插入到最后一个孩子后面，或者直接插在父节点后面
            var insertId = pMap[pId] && pMap[pId][pMap[pId].length - 1] || pId;
            $('#' + insertId, $treeTable).after($trs);
            initRelation($trs);
        };

        return $treeTable;
    };
})(jQuery);